package com.pactera.asmp.server.job.dispatch.impl.task;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.google.common.collect.Lists;
import com.pactera.asmp.server.common.constants.*;
import com.pactera.asmp.server.common.email.IMailService;
import com.pactera.asmp.server.common.exception.CustomException;
import com.pactera.asmp.server.common.logprint.utils.CollectionUtils;
import com.pactera.asmp.server.common.logprint.utils.StringUtils;
import com.pactera.asmp.server.common.utils.ExcelUtil;
import com.pactera.asmp.server.dao.*;
import com.pactera.asmp.server.entity.*;
import com.pactera.asmp.server.job.dispatch.BaseDispatchBus;
import com.pactera.asmp.server.job.dispatch.impl.AsmpTaskDispatchBus;
import com.pactera.asmp.server.job.dispatch.impl.BaseManager;
import com.pactera.asmp.server.pdf.PdfProjectTestReport;
import com.pactera.asmp.server.job.dispatch.IDeviceEvent;
import com.pactera.asmp.server.job.dispatch.ITaskEvent;
import com.pactera.asmp.server.pojo.*;
import com.pactera.asmp.server.service.TaskService;
import com.pactera.asmp.server.service.TestReportServiceImpl;
import com.pactera.asmp.server.utils.DateUtil;
import com.pactera.asmp.server.utils.MinioUtils;
import com.pactera.asmp.server.vo.ColdHotStartupRecord;
import com.pactera.asmp.server.vo.ExcelDataVo;
import com.pactera.asmp.server.vo.ReportMemoryRecord;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 任务管理器
 */
@Slf4j
@Component
public class TaskManager extends BaseManager {

    @Autowired
    private TaskDataRepository repository;

    @Autowired
    private TestReportMapper mTestReportMapper;

    @Autowired
    private ProjectModuleMapper projectModuleMapper;

    @Autowired
    private TestReportServiceImpl mTestReportServiceImpl;

    @Autowired
    private TaskDeviceMapper taskDeviceMapper;

    @Autowired
    private DeviceInfoMapper deviceInfoMapper;

    @Autowired
    private MasterComputerMapper masterComputerMapper;

    @Autowired
    private UserProjectMapper userProjectMapper;

    @Autowired
    private ProjectProductionConfigMapper projectProductionConfigMapper;

    @Autowired
    private TaskMapper taskMapper;

    @Value("${export.temp.file-path}")
    private String tempFilePath;

    //@Autowired
    private TaskService taskService;

    public void setTaskService(TaskService taskService) {
        this.taskService = taskService;
    }

    @Value("${minio.url}")
    private String url;

    @Value("${minio.bucketName}")
    private String buckName;

    @Value("${spring.web.url}")
    private String webUrl;

    @Autowired
    private MinioUtils minioUtils;

    @Autowired
    private TaskReportFileMapper taskReportFileMapper;

    @Override
    public void deviceEventHandler(IDeviceEvent event) {
        if (event.getType().equals(DeviceEventType.DEVICE_QUEUE_OCCUPY)) {
            //如果全部抢占不成功， 任务失败
            handleOccupyFail(event);
        }
    }

    @Override
    public void taskHandler(ITaskEvent event) {
        if (event.getType().equals(TaskEventType.TASK_CREATE)) {
            //创建任务， 发送抢占事件
            handleTaskCreate(event);
        }
        if (event.getType().equals(TaskEventType.TASK_FAIL)) {
            //如果都完成，那么，===》发出任务完成事件
            handleTaskNoDeviceFail(event);
        }

        if (event.getType().equals(TaskEventType.TASK_COMPLETE)) {
            TaskDTO taskMsg = JSONObject.parseObject(event.getData(), TaskDTO.class);
            handleComplete(taskMsg);
        }

        if (event.getType().equals(TaskEventType.TASK_SENDEMAIL)) {
            TaskDTO taskMsg = JSONObject.parseObject(event.getData(), TaskDTO.class);
            taskReportEmail(taskMsg.getId(), taskMsg.getUserId());
        }
        /*if (event.getType().equals(TaskEventType.SUBTASK_SUCCESS)) {
            //如果都完成，那么，===》发出任务完成事件
            handleSubtaskComplete(event);
        }*/
    }

    private void handleComplete(TaskDTO taskMsg){
        TaskDTO task = repository.getTaskHistoryById(taskMsg.getId());

        try {
            repository.modifyTimerTaskStatus(task);
        }catch (Exception e){
            log.error("modifyTask");
        }

    }


    /**
     * 任务创建事件处理, 发起准备抢占事件
     * @param event 事件
     */
    private void handleTaskCreate(ITaskEvent event) {
        //获取事件信息
        Integer taskId = event.getTaskId();
        //查询
        TaskDTO task = repository.getTaskHistoryById(taskId);
        if (task == null) {
            log.error("getTaskHistoryById,taskId={}",taskId);
            this.sleep(200L);
            handleTaskCreate(event);
            return;
        }
        //更新task状态为1
        if (task.getStatus().equals(TaskStatus.TASK_WAIT.getValue())) {
            task.setStatus(TaskStatus.TASK_EXEC.getValue());
        }
        task.setExecTime(LocalDateTime.now());
        task.setExeStartTime(LocalDateTime.now());
        try {
            repository.modifyTask(task);
        }catch (Exception e){
            log.error("modifyTask");
        }
        //获取需要运行设备列表
        List<TaskDevice> taskDeviceList = repository.getTaskDeviceListById(taskId);
        if (CollectionUtils.isNotEmpty(taskDeviceList)){
            for(TaskDevice taskDevice:taskDeviceList) {
                //发出事件
                log.info("准备占用设备：taskId {}, duid {}, auxDuid {}.", taskDevice.getTaskId(), taskDevice.getDuid(), taskDevice.getAuxDuid());
                sendTaskDeviceEvent(taskDevice, DeviceEventType.DEVICE_PREPARE_OCCUPY, event);
            }
        }
    }

    /**
     * 子任务完成， 如果都完成，那么。。。，发出任务完成事件
     */
    /*private void handleSubtaskComplete(ITaskEvent event){
        if( ! event.getDataType().equals(Subtask.class)){
           log.error("handleSubtaskComplete datatype not match");
           return;
        }
        //获取事件信息
        Subtask subtaskMsg = JSONObject.parseObject(event.getData(), Subtask.class);
        Integer taskId = subtaskMsg.getTaskId().intValue();
        //查询
        TaskDTO  task = repository.getTaskHistoryById(taskId);
        if(task == null){
            log.error("repository.getTaskHistoryById is null taskId={}",taskId);
            return;
        }
        int sum = task.getSuccessNumber() + task.getFailNumber();
        //执行完成
        if(sum == task.getExeNumber() ) {
            try {
                //更新状态为完成
                repository.modifyTaskStatusById(taskId, TaskStatus.TASK_COMPLETE.getValue());
                //广播事件
                sendTaskEvent(task, TaskEventType.TASK_COMPLETE);
            }catch (Exception e){
                log.error("",e);
            }
        }
    }*/


    private void handleTaskNoDeviceFail(ITaskEvent event){
        if( ! event.getDataType().equals(TaskDTO.class)){
            log.error("handleTaskFail datatype not match");
            return;
        }
        //获取事件信息
        TaskDTO taskMsg = JSONObject.parseObject(event.getData(), TaskDTO.class);
        Integer taskId = taskMsg.getId();
        List<TaskDevice> taskDeviceList = repository.getTaskDeviceListById(taskId);
        try {
            //更新状态为完成
            repository.modifyTaskStatusAndTDListById
                    (taskId, TaskStatus.TASK_NO_DEVICE_FAIL.getValue(),taskDeviceList,OccupyStatus.RELEASED.getValue());
        }catch (Exception e){
            log.error("modifyTaskStatusById ",e);
        }
    }

    /**
     * //抢占失败事件处理  如果所需Device都抢占失败，那么===》发布任务失败事件
     * @param event 事件
     */
    private void handleOccupyFail(IDeviceEvent event){
        if(!event.getDataType().equals(TaskDevice.class)){
            //log.error
            return;
        }
        //检查一下，是否所有都是排队状态
        TaskDevice taskDevice = JSONObject.parseObject(event.getData(), TaskDevice.class);
        List<TaskDevice> taskDeviceList = repository.getTaskDeviceListById(taskDevice.getTaskId().intValue());
        if(CollectionUtils.isNotEmpty(taskDeviceList)){
            for (TaskDevice td : taskDeviceList){
                //如果有一个不是排队状态
                if(!td.getOccupyStatus().equals(OccupyStatus.QUEUE_OCCUPY.getValue())){
                    return;
                }
            }
        }
        TaskDTO task = repository.getTaskHistoryById(taskDevice.getTaskId().intValue());
        //广播事件
        sendTaskEvent(task, TaskEventType.TASK_FAIL, event);

    }

    public void startTask(TaskDTO task){
        sendTaskEvent(task, TaskEventType.TASK_CREATE);
    }

    public void prepareTaskDevice(List<String> duids, TaskDTO histTask) throws Exception {
        List<TaskDevice> tdList = new ArrayList<>();
        for(String duid : duids){
            DeviceInfo di = repository.getDeviceByDuid(duid);
            if(di != null){
                TaskDevice taskDevice = buildTaskDevice(di, histTask);
                tdList.add(taskDevice);
            }
        }
        repository.createTaskDeviceList(tdList);
    }

    public boolean prepareTaskDevice(TaskDeviceInfo taskDeviceInfo, TaskDTO histTask) throws Exception {
        List<TaskDevice> tdList = new ArrayList<>();

        DeviceInfo di = repository.getDeviceByDuid(taskDeviceInfo.getDuid());
        if(di != null){
            TaskDevice taskDevice = buildTaskDevice(di, histTask);
            taskDevice.setAuxDuid(taskDeviceInfo.getAuxDuid());
            if(isDeviceBusyForScript(di)){
                histTask.setStatus(TaskStatus.TASK_NO_DEVICE_FAIL.getValue());
                histTask.setFailReason("设备被占用于编辑脚本duid="+taskDeviceInfo.getAuxDuid());
                repository.modifyTask(histTask);
                return false;
            }
            //check auxDuid
            if(StringUtils.isNotEmpty(taskDeviceInfo.getAuxDuid())){
                if(!checkAuxDuidBusy(taskDeviceInfo.getAuxDuid())){
                    log.info("check aux duid:{},is busy", taskDeviceInfo.getAuxDuid());
                    histTask.setStatus(TaskStatus.TASK_NO_DEVICE_FAIL.getValue());
                    histTask.setFailReason("辅助设备被占用auxDuid="+taskDeviceInfo.getAuxDuid());
                    repository.modifyTask(histTask);
                    return false;
                }
            }
            tdList.add(taskDevice);
        }

        repository.createTaskDeviceList(tdList);
        return true;
    }

    private boolean isDeviceBusyForScript(DeviceInfo di){
        if (di.getStatus() == DeviceStatus.BUSY.getValue()){
            List<TaskDevice> list = repository.getTaskDeviceListByDeviceAndStatus(di.getDuid(), OccupyStatus.OCCUPIED.getValue());
            if(CollectionUtils.isEmpty(list)) {
                //设备忙是因为编辑脚本
                return true;
            }
        }
        return false;
    }

    private boolean checkAuxDuidBusy(String duid){
        ////check auxDuid , 只要忙就得失败，
        // 只要有taskDevice 有auxDuid并且非释放状态 ，也得失败
        DeviceInfo di = repository.getDeviceByDuid(duid);
        if(di != null){
            if (di.getStatus() != DeviceStatus.FREE.getValue()){
                return false;
            }
            //如果占据或排队，deviceInfo一定是忙碌busy,除非是还没有占有的初始情况
            List<TaskDevice> list = repository.getTaskDeviceListByDeviceAndStatus(duid, OccupyStatus.INIT.getValue());
            if(CollectionUtils.isNotEmpty(list)){
                return false;
            }
        }
        return true;
    }

    public boolean prepareTaskDeviceByTaskDeviceInfoList(List<TaskDeviceInfo> tdiList, TaskDTO histTask) throws Exception {
        List<TaskDevice> tdList = new ArrayList<>();
        for(TaskDeviceInfo tdi : tdiList){
            DeviceInfo di = repository.getDeviceByDuid(tdi.getDuid());
            if(di != null){
                TaskDevice taskDevice = buildTaskDevice(di, histTask);
                taskDevice.setAuxDuid(tdi.getAuxDuid());
                if(isDeviceBusyForScript(di)){
                    histTask.setStatus(TaskStatus.TASK_NO_DEVICE_FAIL.getValue());
                    histTask.setFailReason("设备被占用于编辑脚本duid="+tdi.getDuid());
                    repository.modifyTask(histTask);
                    return false;
                }
                //check auxDuid
                if(StringUtils.isNotEmpty(tdi.getAuxDuid())){
                    if(!checkAuxDuidBusy(tdi.getAuxDuid())){
                        log.info("check aux duid:{},is busy",tdi.getAuxDuid());
                        histTask.setStatus(TaskStatus.TASK_NO_DEVICE_FAIL.getValue());
                        histTask.setFailReason("辅助设备被占用auxDuid="+tdi.getAuxDuid());
                        repository.modifyTask(histTask);
                        return false;
                    }
                }
                tdList.add(taskDevice);
            }
        }
        repository.createTaskDeviceList(tdList);
        return true;
    }

    private TaskDevice buildTaskDevice(DeviceInfo di,TaskDTO histTask){
        TaskDevice taskDevice = new TaskDevice();
        taskDevice.setOccupyStatus(OccupyStatus.INIT.getValue());
        taskDevice.setDuid(di.getDuid());
        taskDevice.setTaskId(Long.valueOf(histTask.getId()));
        taskDevice.setSupportAuxiliary((byte)0);
        long count = repository.countCanInfoByDuid(di.getDuid());
        if(count>0){
            taskDevice.setSupportCan((byte)1);
        }else{
            taskDevice.setSupportCan((byte)0);
        }
        taskDevice.setCreateTime(new Date());
        return taskDevice;
    }

    @Override
    protected BaseDispatchBus initDispatcher() {
        return AsmpTaskDispatchBus.getDispatchBus();
    }

    @Override
    public String getBussinessType() {
        return TaskManager.class.getSimpleName();
    }

    @Autowired
    private IMailService emailService;

    private static final String TEMPLATE_FILENAME = "asmp_email_report_template.html";
    private static final String TITLE_NAME = "任务执行情况";

    public void taskReportEmail(Integer taskId, Integer userId){
        if(userId == null|| taskId == null){
            return;
        }

        TaskDTO taskDTO = repository.getTaskHistoryById(taskId);
        TaskDTO task = taskMapper.getTaskById(taskDTO.getParentId());
        List<UserProject> userProjects = new ArrayList<>();
        if(taskDTO.getType().intValue() == 2) {
            ProjectProductionConfigExample example = new ProjectProductionConfigExample();
            example.createCriteria().andProjectIdEqualTo(taskDTO.getProjectId());
            List<ProjectProductionConfig> projectProductionConfigs = projectProductionConfigMapper.selectByExample(example);
            if(CollectionUtils.isNotEmpty(projectProductionConfigs) && projectProductionConfigs.get(0).getReportSendTo().intValue() == 2) {
                // 不发送
                return;
            }else if(CollectionUtils.isNotEmpty(projectProductionConfigs) && projectProductionConfigs.get(0).getReportSendTo().intValue() == 0) {
                // 发送给所有人
                userProjects.addAll(userProjectMapper.querySelective(new UserProject(){{setProjectId(taskDTO.getProjectId());}}));
            }else {
                // 开始邮件接收的人
                userProjects.addAll(userProjectMapper.querySelective(new UserProject(){{setProjectId(taskDTO.getProjectId()); setNeedSendMail(1);}}));
            }
        }else {
            userProjects.addAll(userProjectMapper.querySelective(new UserProject(){{setProjectId(taskDTO.getProjectId()); setNeedSendMail(1);}}));
        }
        List<Integer> userIds = Lists.newArrayList();
        if(CollectionUtils.isNotEmpty(userProjects)) {
            userIds.addAll(userProjects.stream().map(UserProject::getUserId).collect(Collectors.toList()));
        }
        userIds.add(userId);
        List<User> users = repository.findUserByIds(userIds.stream().distinct().collect(Collectors.toList()));
        if(CollectionUtils.isEmpty(users)){
            return ;
        }
        List<String> toEmailList = users.stream().filter(u -> StringUtils.isNotEmpty(u.getEmail())).map(User::getEmail).distinct().collect(Collectors.toList());
        if(CollectionUtils.isEmpty(toEmailList)){
            return ;
        }
        try {
            Thread.sleep(2000L);
        } catch (InterruptedException e) {
            log.error(e.getMessage());
        }
        String[] toEmails=toEmailList.toArray(new String[toEmailList.size()]);
        String[] ccEmails=new String[]{};
        String[] attachmentPath = new String[]{};
        String templateName = TEMPLATE_FILENAME;
        EmailReportDTO emailReportDTO = queryAndBuildHashMapForEmail(taskId);
        // 邮件标题：项目名称- 任务名称-执行结果-执行时间
        String minioFilePath = url + "/" + buckName + "/";

        File excelFile1 = null;
        File excelFile2 = null;
        File excelFile3 = null;
        try {
            File pdfFile = PdfProjectTestReport.generateFile(emailReportDTO, minioFilePath, false, null);
            String subject = String.format("%s_%s_%d-%d-%d_%s", emailReportDTO.getProjectName(),
                    emailReportDTO.getTaskName(), emailReportDTO.getSuccessNum() == null ? 0 : emailReportDTO.getSuccessNum(), emailReportDTO.getFailNum() == null ? 0 : emailReportDTO.getFailNum(),
                    emailReportDTO.getWaitNum() == null ? 0 : emailReportDTO.getWaitNum(),
                    StringUtils.isNotEmpty(emailReportDTO.getExeStartTime())
                            ? emailReportDTO.getExeStartTime().replace("-", "").replace(":", "").replace(" ", "")
                            : "");

            log.info("email subject:{}", subject);
            List<File> fileList = new ArrayList<>();
            if(taskDTO.getType()  == 4) {
                ExcelDataVo excelData1 = taskService.getExcelDataVoForHMI(task);
                String fileName1 = "HMI性能分析.xlsx";
                excelFile1 = ExcelUtil.generateExcelFileByTemplate2("hmi-report-template.xlsx", tempFilePath, fileName1, excelData1, ColdHotStartupRecord.class, 1);
                fileList.add(excelFile1);

                saveExcelFile(task, excelFile1, fileName1,"03");
            }
            if(taskDTO.getType() == 4) {
                ExcelDataVo excelData2 = taskService.getExcelDataVoForMemory(task.getId());
                String fileName2 = "memory.xlsx";
                excelFile2 = ExcelUtil.generateExcelFileByTemplate2("memory-report-template.xlsx", tempFilePath, fileName2, excelData2, ReportMemoryRecord.class, 1);
                fileList.add(excelFile2);

                ExcelDataVo excelData3 = taskService.getExcelDataVoForTop(taskId);
                String fileName3 = "top.xlsx";
                excelFile3 = ExcelUtil.generateExcelFileByTemplate2("top-report-template.xlsx", tempFilePath, fileName3, excelData3, ReportMemoryRecord.class, 1);
                fileList.add(excelFile3);

                saveExcelFile(task, excelFile2, fileName2,"02");
                saveExcelFile(task, excelFile3, fileName3,"01");
            }

            emailService.sendBatchMailByTemplate(toEmails, ccEmails, subject,
                    attachmentPath, templateName, JSONObject.parseObject(JSONObject.toJSONString(emailReportDTO), Map.class), pdfFile, fileList, taskDTO.getProjectId());
        } catch (Exception e) {
            log.error("emailMock error: ",e);
        } finally {
//            if (excelFile1 != null) {
//                excelFile1.delete();
//            }
//            if (excelFile2 != null) {
//                excelFile2.delete();
//            }
//            if (excelFile3 != null) {
//                excelFile3.delete();
//            }
        }
    }

    private void saveExcelFile(TaskDTO task, File excelFile1, String fileName1,String fileBusinessType) {
        String fileId ="";
        FileInputStream fileInputStream = null;
        try {
            fileInputStream = new FileInputStream(excelFile1);
            fileId = minioUtils.uploadFile(fileInputStream, fileName1,null );
            TaskReportFile record = new TaskReportFile();
            record.setCreateTime(new Date());
            record.setFileId(fileId);
            record.setFileBusinessType(fileBusinessType);
            record.setFileName(fileName1);
            record.setTaskId(task.getId().longValue());
            taskReportFileMapper.insertSelective(record);
        } catch (Exception e) {
            log.error("excel file upload error: ", e);
            throw new CustomException(ResultCode.UPLOAD_ERROR);
        }finally {
            if(fileInputStream!=null){
                try {
                    fileInputStream.close();
                } catch (IOException e) {
                    log.error("excel file close error: ", e);
                }
            }
        }

    }


    public EmailReportDTO queryAndBuildHashMapForEmail(Integer taskId){
        EmailReportDTO emailReportDTO = new EmailReportDTO();
        TaskDTO taskDTO = repository.getTaskHistoryById(taskId);
        SubtaskDistribute subtaskDistribute = repository.getSubtaskDistributeByTaskId(Long.valueOf(taskId));
        TestReportSearchDTO testReportSearchDTO = new TestReportSearchDTO();
        testReportSearchDTO.setTaskId(taskId);
        testReportSearchDTO.setStatus(1);
        List<TestReport> testReports = repository.queryTestReportList(testReportSearchDTO);
        ProjectInfo projectInfo = repository.getProjectInfo(taskDTO.getProjectId());
        emailReportDTO.setTitle1(TITLE_NAME);
        emailReportDTO.setProjectName(projectInfo==null?"":projectInfo.getProjectName());
        emailReportDTO.setType(taskDTO.getType());
        emailReportDTO.setTaskName(taskDTO.getName());
        emailReportDTO.setScriptNum(subtaskDistribute.getScriptSize());
        emailReportDTO.setExecNum(taskDTO.getExeNumber());
        emailReportDTO.setFailReason(taskDTO.getFailReason());
        emailReportDTO.setNeedExecSum(subtaskDistribute.getNeedExecSum());
        emailReportDTO.setScriptExecuteNum(subtaskDistribute.getExecSum());
        emailReportDTO.setSuccessExecuteNum(testReports.size());
        emailReportDTO.setUsername(taskDTO.getUserName());
        emailReportDTO.setCreateTime(taskDTO.getCreateTime().format(DateTimeFormatter.ofPattern(DateUtil.DATE_TIME_FORMAT_YYYY_MM_DD_HH_MI_SS)));
        emailReportDTO.setPackages(taskDTO.getPackages());
        emailReportDTO.setMonkeyExeNumber(taskDTO.getMonkeyExeNumber());
        TaskDTO curtaskDTO = taskMapper.getTaskById(taskDTO.getParentId());
        if(null != curtaskDTO) {
            if(null != curtaskDTO.getExeStartTime()) {
                emailReportDTO.setExeStartTime(curtaskDTO.getExeStartTime().format(DateTimeFormatter.ofPattern(DateUtil.DATE_TIME_FORMAT_YYYY_MM_DD_HH_MI_SS)));
            }
            if(null != curtaskDTO.getExeEndTime()) {
                emailReportDTO.setExeEndTime(curtaskDTO.getExeEndTime().format(DateTimeFormatter.ofPattern(DateUtil.DATE_TIME_FORMAT_YYYY_MM_DD_HH_MI_SS)));
            }
        }
        switch (taskDTO.getCycleType()) {
        case 0:
            emailReportDTO.setTaskType("定期执行");
            break;
        case 1:
            emailReportDTO.setTaskType("延时执行");
            break;
        case 2:
            emailReportDTO.setTaskType("立刻执行");
            break;
        }
        emailReportDTO.setTaskStatus("执行完成");
        // 获取测试报告数据
        List<SelectTestReportResult> reportReslutList = getSelectTestReportResult(taskId, taskDTO.getProjectId());
        if(taskDTO.getType() == 3) {
            if(CollectionUtils.isNotEmpty(reportReslutList)) {
                emailReportDTO.setMonkeyTestReportResult(reportReslutList.get(0));
                if(StringUtils.isNotEmpty(reportReslutList.get(0).getMonkeyReport())) {
                    List<Map<String, String>> list = JSONObject.parseObject(reportReslutList.get(0).getMonkeyReport(), new TypeReference<List<Map<String, String>>>(){});
                    Integer crashTotalCnt = 0;
                    Integer narTotalCnt = 0;
                    for(Map<String, String> map : list) {
                        crashTotalCnt += Integer.parseInt(map.get("crashCount"));
                        narTotalCnt += Integer.parseInt(map.get("anrCount"));
                    }
                    emailReportDTO.setCrashTotalCnt(crashTotalCnt);
                    emailReportDTO.setNarTotalCnt(narTotalCnt);
                }
            }
        }else {
            Map<Integer, List<SelectTestReportResult>> testReportResultMap= reportReslutList.stream().collect(Collectors.groupingBy(SelectTestReportResult::getCount));
            emailReportDTO.setTestReportResultMap(testReportResultMap);
        }
        getTaskDevices(taskId, emailReportDTO);
        if(taskDTO.getType() != 3 && taskDTO.getType()!=4) {
            ResponseResult result= mTestReportServiceImpl.getTestReportDataByTask(taskDTO.getParentId());
            if(result.getCode() == 200) {
                emailReportDTO.setReportByTask(result.getData());
            }
        }
        emailReportDTO.setWebUrl(webUrl+taskId);

        //冷热启动
        HashMap<String ,List<TaskStartupInfo>> map = new HashMap<>();
        List<TaskStartupInfo> taskStartupInfos = mTestReportServiceImpl.getTaskStartupInfo(taskDTO.getId());
        if(CollectionUtils.isNotEmpty(taskStartupInfos)) {
            for (TaskStartupInfo taskStartupInfo : taskStartupInfos){
                List<TaskStartupInfo> list = map.get(taskStartupInfo.getPackageName());
                if(list == null){
                    list = new ArrayList<>();
                    map.put(taskStartupInfo.getPackageName(), list);
                }
                list.add(taskStartupInfo);
            }
        }
        emailReportDTO.setStartupMap(map);
        emailReportDTO.setSheetData(taskService.buildHmiStartSheetData(curtaskDTO));
        // 获取执行设备
        return emailReportDTO;
    }

    private List<SelectTestReportResult> getSelectTestReportResult(Integer hisTaskId, Integer projectId){
        //--------------------------------------------------------------------------------------------------------------------------------

        //获取任务对应的项目模块
        ProjectModuleSearch search = new ProjectModuleSearch();
        search.setProjectId(projectId);
        search.setStatus(1);
        List<ProjectModuleDTO> moduleList = projectModuleMapper.select(search);
        Map<Integer, ProjectModuleDTO> projectModuleMap= null;
        if(!CollectionUtils.isEmpty(moduleList)) {
            projectModuleMap = moduleList.stream().collect(Collectors.toMap(ProjectModuleDTO::getId, x -> x));
        }

        TestReportSearchDTO data = new TestReportSearchDTO();
        data.setTaskId(hisTaskId);
//        data.setCount(count);
        List<TestReport> testReports = mTestReportMapper.select2(data);
        List<SelectTestReportResult> testReportResult = new ArrayList<>();
        for(TestReport report : testReports){
            SelectTestReportResult rt = new SelectTestReportResult();
            rt.setId(report.getId());
            rt.setAction(report.getAction());
            rt.setContent(report.getContent());
            rt.setCount(report.getCount());
            rt.setStatus(report.getStatus());
            rt.setVideoFileIndex(report.getVideoFileIndex());
            rt.setLogFileIndex(report.getLogFileIndex());
            rt.setCanLogFileId(report.getCanLogFileId());
            rt.setHtmlReportFileId(report.getHtmlReportFileId());
            rt.setCreateTime(report.getCreateTime());
            rt.setScriptName(report.getScriptName());
            rt.setMonkeyOrder(report.getMonkeyOrder());
            rt.setMonkeyReport(report.getMonkeyReport());
            if(null != projectModuleMap && projectModuleMap.containsKey(report.getModuleId())) {
                rt.setModuleName(projectModuleMap.get(report.getModuleId()).getName());
            }
            rt.setErrorVideoInfos(mTestReportServiceImpl.getErrorVideoInfosByTestReportId(report.getId()));
            rt.setTestedReport(mTestReportServiceImpl.getTestReportApplicationResponseTime(report.getId()));
            testReportResult.add(rt);
        }

        return testReportResult;
    }

    private void getTaskDevices(Integer hisTaskId, EmailReportDTO emailReportDTO){
        TaskDeviceExample example =new TaskDeviceExample();
        example.createCriteria().andTaskIdEqualTo(hisTaskId.longValue()).andIsDeletedEqualTo(0);
        List<TaskDevice> taskDevices = taskDeviceMapper.selectByExample(example);
        if(CollectionUtils.isEmpty(taskDevices)) {
            return;
        }
        List<String> duids = taskDevices.stream().map(TaskDevice::getDuid).distinct().collect(Collectors.toList());
        if(taskDevices.stream().anyMatch(taskDevice -> StringUtils.isNotEmpty(taskDevice.getAuxDuid()))) {
            duids.addAll(taskDevices.stream().filter(taskDevice -> StringUtils.isNotEmpty(taskDevice.getAuxDuid())).map(TaskDevice::getAuxDuid).distinct().collect(Collectors.toList()));
        }
        // 获取设备信息
        List<DeviceInfo> deviceInfos = deviceInfoMapper.selectByDuids(duids, null);
        if(CollectionUtils.isEmpty(deviceInfos)) {
            return;
        }
        // 获取上位机信息
        List<MasterComputer> masterComputers =masterComputerMapper.findMasterComputerByIds(deviceInfos.stream().map(DeviceInfo::getMasterComputerId).distinct().collect(Collectors.toList()));
        if(CollectionUtils.isEmpty(masterComputers)) {
            return;
        }
        emailReportDTO.setDeviceInfos(deviceInfos);
        emailReportDTO.setMasterComputers(masterComputers);
    }
}
